import 'dart:async';
import 'package:event_bus/event_bus.dart';
import 'package:get/get.dart';
import 'package:shimo_app/bus/protocol/abort.dart';
import 'package:shimo_app/bus/protocol/adjustment.dart';
import 'package:shimo_app/bus/protocol/component_action.dart';
import 'package:shimo_app/bus/protocol/init.dart';
import 'package:shimo_app/bus/protocol/poll.dart';
import 'package:shimo_app/bus/protocol/protocol.dart';
import 'package:shimo_app/bus/protocol/resume.dart';
import 'package:shimo_app/bus/protocol/sample.dart';
import 'package:shimo_app/bus/protocol/sensor.dart';
import 'package:shimo_app/bus/protocol/task.dart';
import 'package:shimo_app/bus/serial_port.dart';
import 'package:shimo_app/bus/struct/boardStatus.dart';
import 'package:shimo_app/bus/struct/error.dart';
import 'package:shimo_app/bus/struct/log.dart';
import 'package:shimo_app/bus/struct/task_progress.dart';
import 'package:shimo_app/bus/struct/task_result.dart';
import 'package:shimo_app/pages/components/hint.dart';

import 'frame/frame.dart';
import 'package:shimo_app/pages/components/durationDialog.dart';

/// 总线通信管理器 - 负责与硬件设备通过串口进行通信
class Bus {
  late Timer _busTimer; // 总线轮询定时器
  bool _isBusy = false; // 通信繁忙标志，防止并发操作
  bool _busErr = false; // 总线错误状态标志

  // late SocketServer _socket;  // 网络通信（已注释）
  final MySerialPort _serialPort = MySerialPort(); // 串口通信实例
  int _busErrorCounter = 0; // 总线错误计数器
  bool _initializing = false; // 初始化状态标志
  EventBus _eventBus = EventBus(); // 事件总线，用于组件间通信
  List<StreamSubscription> _events = []; // 事件订阅列表，用于资源管理

  // 各种事件监听器
  Function(BoardStatus)? boardStatusListener; // 电路板状态监听器
  Function(TaskProgress)? _taskProgressListener; // 任务进度监听器
  Function(List<SetComponentError>)? _errorListener; // 错误信息监听器
  Function(DebugLog)? _logListener; // 日志监听器

  List<SetComponentError> _errors = []; // 错误信息列表
  int _channelMode = 1; // 通道模式（1=单通道，2=双通道）

  /// 启动总线通信
  Future<bool> start(String name, int channelMode) async {
    print("尝试打开串口:${name}");
    _channelMode = channelMode;

    // 打开串口
    final r = await _serialPort.open(name, 9600);
    if (!r) {
      print("===打开串口失败====");
      //todo:抛错
    }

    if (r) {
      // 启动总线轮询
      _busLoop();

      // 注册各种事件监听

      // 电路板状态事件监听
      _events.add(_eventBus.on<BoardStatusEvent>().listen((event) async {
        print("检测到电路板状态:${event.status.name}");
        if (boardStatusListener == null) return;
        boardStatusListener!(event.status);

        // 如果检测到启动后状态，自动执行初始化
        if (event.status == BoardStatus.BOARD_AFTERBOOT) {
          await 200.milliseconds.delay(); // 延迟200ms确保设备就绪
          await initBoard(); // 执行初始化
        }
      }));

      // 任务进度事件监听
      _events.add(_eventBus.on<TaskProgress>().listen((event) {
        if (_taskProgressListener == null) return;
        print("获取任务进度:${event.taskId}-${event.pos}-${event.state}");
        _taskProgressListener!(event);
      }));

      // 组件错误事件监听
      _events.add(_eventBus.on<SetComponentError>().listen((event) {
        if (_errorListener == null) return;

        // 避免重复添加相同错误
        final existed = _errors
            .firstWhereOrNull((element) => element.content == event.content);
        if (existed != null) return;

        print("set component error:${event.component}:${event.content}");
        _errors.add(event);
        _errorListener!(_errors); // 通知监听器
      }));

      // 清除组件错误事件监听
      _events.add(_eventBus.on<ClearComponentError>().listen((event) {
        if (_errorListener == null) return;

        final existed =
            _errors.indexWhere((element) => element.content == event.content);
        if (existed == -1) return;

        print("clear component error:${event.content}");
        _errors.removeAt(existed);
        _errorListener!(_errors); // 通知监听器
      }));

      // 调试日志事件监听
      _events.add(_eventBus.on<DebugLog>().listen((event) {
        if (_logListener == null) return;
        _logListener!(event);
      }));
    }
    return r;
  }

  /// 关闭总线通信，释放资源
  void close() {
    // 取消所有事件订阅
    for (var i in _events) {
      i.cancel();
    }
    _eventBus.destroy(); // 销毁事件总线
    _busTimer.cancel(); // 停止轮询定时器
    _serialPort.close(); // 关闭串口
  }

  /// 获取可用串口列表
  List<Map<String, String>> getSerialPorts() {
    return _serialPort.getAllPorts();
  }

  /// 标记准备完成，可以重新初始化
  void readyToInit() {
    _initializing = false;
  }

  /// 初始化电路板
  Future<bool> initBoard() async {
    if (_initializing) {
      return true; // 防止重复初始化
    }

    print("执行初始化动作...");
    showHint("正在初始化,请稍等...", HintType.WARNING);
    showDurationDialog("正在初始化,请稍等..."); // 显示进度对话框

    _initializing = true;
    final init = Init(); // 创建初始化协议实例
    final frame = Frame(null); // 创建数据帧

    // 构建初始化数据帧
    Map<int, int> components = {100: 1, 120: 1, 140: 1, 160: 1}; // 组件配置
    frame.pushByte(4); // 组件数量

    // 添加组件ID到数据帧
    for (var i in components.keys) {
      for (var j = 0; j < components[i]!; j++) {
        frame.pushByte(i + j + 1);
      }
    }

    // 发送初始化命令
    final r = await _transmit(init, frame);
    _initializing = false;

    // 关闭对话框并显示结果
    if (Get.isDialogOpen == true) Get.back();
    showHint("初始化${r ? "成功" : "失败"}", r ? HintType.SUCCESS : HintType.DANGER);
    return true;
  }

  /// 设置总线连接状态监听器
  void setBusConnectedListener(Function(bool) listener) {
    listener(_serialPort.opened);
  }

  /// 设置电路板状态监听器
  void setBoardStatusListener(Function(BoardStatus) listener) {
    boardStatusListener = listener;
  }

  /// 设置任务进度监听器
  void setTaskProgressListener(Function(TaskProgress) listener) {
    _taskProgressListener = listener;
  }

  /// 设置错误监听器
  void setErrorListener(Function(List<SetComponentError>) listener) {
    _errorListener = listener;
  }

  /// 设置日志监听器
  void setLogListener(Function(DebugLog) listener) {
    _logListener = listener;
  }

  /// 获取串口打开状态
  bool get serialPortOpened {
    return _serialPort.opened;
  }

  /// 执行组件动作
  Future<bool> componentAction(int componentId, int testId, int arg) async {
    final test = ComponentAction();
    print(
        "start component action,component:${componentId},testId:$testId,arg:$arg");

    // 构建动作数据帧：组件ID + 测试ID + 参数
    final result = await _transmit(
        test, Frame(null).pushByte(componentId).pushByte(testId).pushLong(arg));

    print("component action result:${test.actionResult}|$result");
    return test.actionResult && result; // 返回动作执行结果
  }

  /// 设置样本配置
  Future<bool> setSample(int containerId, List<bool> samples) async {
    final sample = SetSample();

    // 将布尔值转换为整数（0/1）
    final sampleData =
        List.generate(samples.length, (index) => samples[index] ? 1 : 0);

    // 构建样本数据帧：容器ID + 样本数据列表
    final result = await _transmit(
        sample, Frame(null).pushByte(containerId).pushList(sampleData));
    return result;
  }

  /// 部署任务到容器
  Future<bool> deployTask(int containerId, List<TaskDeployData> tasks) async {
    final task = DeployTask();
    final frame = Frame(null);

    // 构建任务数据帧：容器ID + 任务数量 + 每个任务的参数
    frame.pushByte(containerId);
    frame.pushByte(tasks.length);
    for (var i in tasks) {
      frame.pushByte(i.taskId);
      frame.pushLong(i.arg1);
      frame.pushLong(i.arg2);
      frame.pushLong(i.arg3);
    }

    final result = await _transmit(task, frame);
    return result;
  }

  /// 设置调整参数
  Future<bool> setAdjustment(Map<String, int> adjustments) async {
    final adj = Adjustment();
    final frames = Frame(null);

    // 构建调整数据帧：参数数量 + 每个参数的键值对
    frames.pushByte(adjustments.length);
    for (var i in adjustments.keys) {
      print("---adjustment value:$i:${adjustments[i]}");
      frames.pushString(i).pushShort(adjustments[i]!);
    }

    final result = await _transmit(adj, frames);
    return result;
  }

  /// 运行任务（待实现）
  Future<TaskResult> runTask() async {
    return TaskResult.TASK_DONE;
  }

  /// 中止/暂停动作
  Future<bool> abortAction(int containerId, {bool isPause = false}) async {
    final abort = Abort();

    // 构建中止数据帧：容器ID + 暂停标志
    return await _transmit(
        abort, Frame(null).pushByte(containerId).pushByte(isPause ? 1 : 0));
  }

  /// 恢复任务执行
  Future<bool> resume() async {
    final resume = Resume();
    return _transmit(resume, Frame(null)); // 空数据帧
  }

  /// 获取传感器数值
  Future<int> getSensorValue(int componentId, int sensorId) async {
    final sensor = Sensor();

    // 构建传感器数据帧：组件ID + 传感器ID
    await _transmit(
        sensor, Frame(null).pushByte(componentId).pushByte(sensorId));

    return sensor.sensorValue; // 返回传感器数值
  }

  /// 获取总线状态
  int get busState {
    if (_busErrorCounter > 5) {
      return -2; // 严重错误状态
    }
    if (_busErr) {
      return -1; // 一般错误状态
    }
    return 1; // 正常状态
  }

  /// 总线轮询循环
  void _busLoop() {
    final poll = Poll(_eventBus); // 创建轮询协议实例
    int stateCount = 0;

    // 每350ms执行一次轮询
    _busTimer = Timer.periodic(350.milliseconds, (timer) async {
      if (!_isBusy && !_busErr && !_initializing) {
        if (stateCount++ > 3) {
          stateCount = 0;
        }
      }

      print("---busy:${_isBusy}");

      // 如果当前不繁忙，执行轮询
      if (!_isBusy) {
        await _transmit(poll, Frame(null));
      }

      // 错误状态处理
      if (_busErr) {
        if (_busErrorCounter++ >= 5) {
          print("通信断开");
        }
      } else {
        _busErrorCounter = 0; // 重置错误计数器
      }
    });
  }

  /// 传输协议数据（核心通信方法）
  Future<bool> _transmit(Protocol instance, Frame frame) async {
    // 检查总线状态，非轮询/初始化协议在错误状态下不执行
    if ((instance.runtimeType != Poll && instance.runtimeType != Init) &&
        _busErr) {
      return false;
    }

    // 处理耗时操作，防止并发
    if (instance.isTimeConsuming()) {
      int timeCounter = 1500; // 超时计数器（15秒）

      // 等待其他操作完成
      while (_isBusy) {
        await 10.milliseconds.delay();
        if (timeCounter-- / 10 <= 0) return false; // 超时返回失败
      }
      _isBusy = true; // 标记为繁忙
    }

    // 执行协议传输
    _busErr = !await instance.run(_serialPort, frame, _eventBus);

    if (instance.runtimeType == Abort) {
      print("---_busErr:${_busErr}");
    }

    // 释放繁忙状态
    if (instance.isTimeConsuming()) {
      _isBusy = false;
    }

    // 错误处理
    if (_busErr) {
      print("通信异常");
    }

    return !_busErr; // 返回传输结果
  }
}

/// 任务部署数据结构
class TaskDeployData {
  final int taskId; // 任务ID
  final int arg1; // 参数1
  final int arg2; // 参数2
  final int arg3; // 参数3

  TaskDeployData(this.taskId, this.arg1, this.arg2, this.arg3);
}
